﻿using Hardware;
using Hardware.Meter;
using SmartWeighing;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MeterTest
{
    public partial class Form1 : Form
    {

        private Meter meter = new Meter();
        private MeterApi meterApi;
        private SynchronizationContext synchronizationContext = null;

        public Form1()
        {
            InitializeComponent();

            synchronizationContext = SynchronizationContext.Current;
        }

        private void Form1_Load(object sender, EventArgs e)
        {            
            try
            {
                InitSystem();                
            }
            catch (Exception ex)
            {
                lstStatus.Items.Add("初始化仪表设备异常:" + ex.Message);
            }
        }

        private void Meter_ShowHexData(string hexData)
        {
            // 没有数据时直接退出 没有显示数据时退出
            if (string.IsNullOrEmpty(hexData) || !chkShowInfo.Checked) return;
          
            if (lstStatus.InvokeRequired)
            {
                lstStatus.Invoke(new Action(()=> {
                    if (!chkShowType.Checked)
                    {
                        lstStatus.Items.Add(String.Format("{0}#，{1}{2},长度{3}\r\n", 1, "接收Binary数据", Utils.HexString2AscIIString(hexData, Encoding.ASCII), hexData.Length));
                    }
                    else if (chkShowType.Checked)
                    {
                        lstStatus.Items.Add(String.Format("{0}#，{1}{2},长度{3}\r\n", 1, "接收Hex数据", hexData, hexData.Length));                        
                    }
                    lstStatus.SelectedIndex = lstStatus.Items.Count > 0 ? lstStatus.Items.Count - 1 : -1;
                }));
            }
            else
            {
                if (!chkShowType.Checked)
                {
                    lstStatus.Items.Add(String.Format("{0}#，{1}{2},长度{3}\r\n", 1, "接收Binary数据", Utils.HexString2AscIIString(hexData, Encoding.ASCII), hexData.Length));
                }
                else if (chkShowType.Checked)
                {
                    lstStatus.Items.Add(String.Format("{0}#，{1}{2},长度{3}\r\n", 1, "接收Hex数据", hexData, hexData.Length));
                }
                lstStatus.SelectedIndex = lstStatus.Items.Count > 0 ? lstStatus.Items.Count - 1 : -1;
            }            
        }

        private void Meter_DataReceived(double weight, object sender)
        {
            synchronizationContext.Post(UpdateWeightToUI, weight);
        }

        private void UpdateWeightToUI(object text)
        {            
            lbWeight.Text = text.ToString();
        }
        private void Meter_StatusChanged(string param, object sender)
        {
            try
            {
                if (lstStatus.InvokeRequired)
                {
                    lstStatus.Invoke(new Action(()=> {
                        lstStatus.Items.Add(String.Format("{0}#，仪表状态：{1}", 1, param));
                        lstStatus.SelectedIndex = lstStatus.Items.Count > 0 ? lstStatus.Items.Count - 1 : -1;
                    }));
                }
                else
                {
                    lstStatus.Items.Add(String.Format("{0}#，仪表状态：{1}", 1, param));
                    lstStatus.SelectedIndex = lstStatus.Items.Count > 0 ? lstStatus.Items.Count - 1 : -1;
                }                
            }
            catch (Exception ex)
            {
                lstStatus.Items.Add("Meter_StatusChanged Error:" + ex.Message);
                lstStatus.SelectedIndex = lstStatus.Items.Count > 0 ? lstStatus.Items.Count - 1 : -1;
            }
        }


        private void InitSystem()
        {
            string[] comList = { "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "COM10", "COM11", "COM12", "COM13", "COM14", "COM15", "COM16" };
            //串口
            cmbCom.Items.AddRange(comList);

            //停止位与校验位
            foreach (string item in Enum.GetNames(typeof(Parity)))
            {
                cmbParity.Items.Add(item);
            }
            foreach (string item in Enum.GetNames(typeof(StopBits)))
            {
                cmbStopBit.Items.Add(item);
            }

            //创建控件数组 
            ComboBox[] arrType = { cmbMeter };
            ComboBox[] arrCom = { cmbCom };
            ComboBox[] arrBaudrate = { cmbBaudRate };
            ComboBox[] arrStopBits = { cmbStopBit };
            ComboBox[] arrDataBits = { cmbDataBit };
            ComboBox[] arrParity = { cmbParity };
            ComboBox[] arrMeterUnit = { cmbMeterUnit };                       

            //重新赋值配置参数到全局变量
            IniFile configFile = new IniFile(Application.StartupPath + "\\DeviceConfig.ini");
            meter.Type = configFile.ReadValue("Meter", String.Format("Type{0}", 0), 0);
            meter.ComIndex = configFile.ReadValue("Meter", String.Format("ComIndex{0}", 0), 0);
            meter.ComName = configFile.ReadValue("Meter", String.Format("ComName{0}", 0), "COM1");
            meter.BaudIndex = configFile.ReadValue("Meter", String.Format("BaudIndex{0}", 0), 0);
            meter.BaudValue = configFile.ReadValue("Meter", String.Format("BaudValue{0}", 0), 9600);
            meter.stopBits = (System.IO.Ports.StopBits)configFile.ReadValue("Meter", String.Format("StopBits{0}", 0), 0);
            meter.parity = (System.IO.Ports.Parity)configFile.ReadValue("Meter", String.Format("Parity{0}", 0), 0);
            meter.DataBits = configFile.ReadValue("Meter", String.Format("DataBits{0}", 0), 8);
            meter.MeterUnit = configFile.ReadValue("Meter", String.Format("MeterUnit{0}", 0), "KG");
            
            arrType[0].SelectedIndex = meter.Type;
            arrCom[0].SelectedIndex = meter.ComIndex;
            arrBaudrate[0].SelectedIndex = meter.BaudIndex;
            arrStopBits[0].SelectedIndex = (Int16)meter.stopBits;
            arrDataBits[0].Text = meter.DataBits.ToString();
            arrParity[0].SelectedIndex = (Int16)meter.parity;
            arrMeterUnit[0].Text = meter.MeterUnit;            

            configFile = null; arrType = null; arrCom = null; arrBaudrate = null; arrStopBits = null; arrDataBits = null; arrParity = null;
            arrMeterUnit = null; 
            
        }

        /// <summary>
        /// 保存仪表配置
        /// </summary>
        private void SaveMeterConfig()
        {
            this.Cursor = Cursors.WaitCursor;
            try
            {
                this.Cursor = Cursors.WaitCursor;
                
                //创建控件数组
                ComboBox[] arrType = { cmbMeter };
                ComboBox[] arrCom = { cmbCom };
                ComboBox[] arrBaudrate = { cmbBaudRate };
                ComboBox[] arrStopBits = { cmbStopBit };
                ComboBox[] arrDataBits = { cmbDataBit };
                ComboBox[] arrParity = { cmbParity };
                ComboBox[] arrMeterUnit = { cmbMeterUnit };
               

                //保存仪表配置到 DeviceConfig.ini中
                IniFile config = new IniFile(Application.StartupPath + "\\DeviceConfig.ini");

                config.WriteValue("Meter", String.Format("Type{0}", 0), arrType[0].SelectedIndex);
                config.WriteValue("Meter", String.Format("ComIndex{0}", 0), arrCom[0].SelectedIndex);
                config.WriteValue("Meter", String.Format("BaudIndex{0}", 0), arrBaudrate[0].SelectedIndex);
                config.WriteValue("Meter", String.Format("ComName{0}", 0), arrCom[0].Text);
                config.WriteValue("Meter", String.Format("BaudValue{0}", 0), arrBaudrate[0].Text);
                config.WriteValue("Meter", String.Format("StopBits{0}", 0), arrStopBits[0].SelectedIndex);
                config.WriteValue("Meter", String.Format("Parity{0}", 0), arrParity[0].SelectedIndex);
                config.WriteValue("Meter", String.Format("DataBits{0}", 0), arrDataBits[0].Text);
                config.WriteValue("Meter", String.Format("MeterUnit{0}", 0), arrMeterUnit[0].Text);

                //实时更新当前的全局变量                
                meter.Type = arrType[0].SelectedIndex;
                meter.ComIndex = arrCom[0].SelectedIndex;
                meter.ComName = arrCom[0].Text;
                meter.BaudIndex = arrBaudrate[0].SelectedIndex;
                meter.BaudValue = Convert.ToInt32(arrBaudrate[0].Text);
                meter.stopBits = (StopBits)arrStopBits[0].SelectedIndex;
                meter.parity = (Parity)arrParity[0].SelectedIndex;
                meter.DataBits = Convert.ToInt16(arrDataBits[0].Text);
                meter.MeterUnit = arrMeterUnit[0].Text;
                
                config = null; arrType = null; arrCom = null; arrBaudrate = null; arrStopBits = null; arrDataBits = null; arrParity = null;
                arrMeterUnit = null; 

                this.Cursor = Cursors.Default;                
            }
            catch (Exception ex)
            {
                this.Cursor = Cursors.Default;                
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            SaveMeterConfig();            
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            try
            {
                if (meterApi != null && meterApi.meter != null)
                {
                    meterApi.meter.Close();
                    meterApi = null;
                }                
            }
            catch (Exception ex)
            {
                MessageBox.Show("关闭设备失败:" + ex.Message, "操作失败", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            finally
            {
                btnClose.Enabled = false;
                btnOpen.Enabled = true;
            }
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            try
            {
                SaveMeterConfig();

                if (meterApi != null && meterApi.meter != null)
                {
                    if (meterApi.meter.IsOpen) meterApi.meter.Close();
                    meterApi.meter.DataReceived -= Meter_DataReceived;
                    meterApi.meter.StatusChanged -= Meter_StatusChanged;
                    meterApi.meter.ShowHexData -= Meter_ShowHexData;
                    meterApi = null;
                }
                // 清空原来的重量数据
                if (lbWeight.InvokeRequired)
                {
                    lbWeight.Invoke(new Action(() => {
                        lbWeight.Text = "0";
                    }));
                }
                else
                {
                    lbWeight.Text = "0";
                }

                meterApi = new MeterApi(Application.StartupPath + "\\DeviceConfig.ini");
                if (meterApi != null && meterApi.meter != null)
                {
                    meterApi.meter.StatusChanged += Meter_StatusChanged;
                    meterApi.meter.DataReceived += Meter_DataReceived;
                    meterApi.meter.ShowHexData += Meter_ShowHexData;
                    meterApi.meter.ShowHexFlag = chkShowType.Checked;
                    meterApi.meter.Open();
                    btnClose.Enabled = true;
                    btnOpen.Enabled = false;
                }
                else
                {
                    lstStatus.Items.Add("打开仪表设备失败!");
                }
            }
            catch (Exception ex) 
            {
                lstStatus.Items.Add("打开仪表失败:" + ex.Message);
            }
        }

        private void chkShowType_CheckedChanged(object sender, EventArgs e)
        {
            
        }

        private void chkShowInfo_CheckedChanged(object sender, EventArgs e)
        {
            if (chkShowInfo.Checked)
            {
                chkShowType.Enabled = true;
            }
            else
            {
                chkShowType.Enabled = false;
            }
            if (meterApi != null && meterApi.meter != null)
            {
                meterApi.meter.ShowHexFlag = chkShowInfo.Checked;
            }
        }
    }
}
